package com.javabi.unix.parser.ps;

import java.util.ArrayList;
import java.util.List;

import com.javabi.unix.line.LineNumberProcessor;
import com.javabi.unix.line.LineTokenizer;

/**
 * A Process List (ps) parser
 */
public class PsParser extends LineNumberProcessor<List<PsRow>> {

	private PsColumnSet columnSet = new PsColumnSet();
	private List<PsRow> psList = new ArrayList<PsRow>();

	@Override
	public List<PsRow> getResult() {
		if (psList.isEmpty()) {
			throw new IllegalStateException("ps not set");
		}
		return psList;
	}

	@Override
	public boolean processLine(String line, int number) {
		if (number == 1) {
			parseColumnNames(line);
		} else {
			parserPs(line);
		}
		return true;
	}

	private void parseColumnNames(String line) {
		int index = 0;
		LineTokenizer tokenizer = new LineTokenizer(line);
		while (tokenizer.hasNext()) {
			String name = tokenizer.next();
			columnSet.put(name, index++);
		}
	}

	private void parserPs(String line) {
		List<String> row = new ArrayList<String>();

		// Parse the row values
		LineTokenizer tokenizer = new LineTokenizer(line);
		int columns = columnSet.size();
		for (int i = 1; i < columns; i++) {
			String value = tokenizer.next();
			row.add(value);
		}

		// Final row value should take rest of the line (including whitespace)
		// this handles the expected case that the column is "COMMAND"
		String value = tokenizer.remaining();
		row.add(value.trim());

		// Success!
		psList.add(new PsRow(columnSet, row));
	}

}
